<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app"></div>
    <script>
        // 记录当前触发函数是谁
        let activeFunc = null
        function wrap(fn) {
            // 调用fn之前做什么
            activeFunc = fn
            fn()
            // 调用fn之后做什么
        }
        const collection = new Set()
        function reactive (obj) {
            return new Proxy(obj, {
                get(target, key) {
                    // 在这里收集函数，到set里面使用
                    // 如果activeFunc存在的话，就添加到collection里面 
                    if(activeFunc) {
                        collection.add(activeFunc)
                    }
                    return target[key];
                },
                set(target, key, value) {
                    target[key] = value;
                    // 在这里调用的话，就会触发更新，就会使页面发生变化
                    // 这个update 是个例子用以说明，是不能写在这里的
                    // update() 把它注释掉

                    // 在这里触发函数
                    collection.forEach(func=>func())
                    console.log(collection,'collection');
                    return true;
                    // return true 代表set成功
                },
                deleteProperty(target, key) {
                    delete target[key];
                    return true;
                }  
            })
         }
        const app = document.getElementById("app")
        const data = reactive({
            text:'reactive',
            color:'blue'
        })
        const update = ()=>{
            app.innerText = data.text
        }
        const update2 = () =>{
            app.style.color = data.color
        }
        wrap(update)
        wrap(update2)

        // 隔一秒更新文本内容，如果不调用update()，是不会实现更改的
        setTimeout(()=>{
            data.text = 'vue3,reactive'
            data.color = 'red'
            // 如果不调用的话，打印显示是已经更改了，但页面并没有改
            // 我们要实现的是，不调用update() 实现更新
            // 在这里，需要用到es6的proxy。
            // Proxy是ES6的新增特性 能控制外部对对象的访问
            /* 哈哈哈哈哈哈
            new Proxy(target, handler)
            target 被代理对象。handler 对象，其声明了代理 target 的一些操作。new了以后的实例 是代理后的对象。
            每次对new了以后的实例进行获取修改的时候，就会执行 handler 对象上的一些方法，比如get set*/
            // update() 
        },1000)
    </script>
</body>
</html>

<!-- 视频地址 
一 、 https://www.bilibili.com/video/BV1Qh4y1C7Kj/?spm_id_from=333.788.recommend_more_video.-1&v

二 、 https://www.bilibili.com/video/BV1Nz4y1W7g1/?spm_id_from=333.788.recommend_more_video.-1&vd_source=1f030ef96e6981d922f87cbcbd38ac6f
-->

















